#pragma once

#include <memory>
#include <functional>
#include <algorithm>

#include <vector>
#include <list>

namespace sigslot
{
	class Binding;
	class SigSlotBase;

	/*
	 * @brief Base class for objects wishing to receive signals (i.e. have slots)
	 */
	class UILIB_API SigSlotBase
	{
	public:
		virtual ~SigSlotBase();

		void add_binding(const std::shared_ptr<Binding>& b);
		virtual void erase_binding(const std::shared_ptr<Binding>& b);

	private:
		std::list<std::shared_ptr<Binding>> _bindings;
	};


	class UILIB_API Binding : public std::enable_shared_from_this<Binding>
	{
	public:
		Binding() = delete;
		Binding(const Binding& o) = delete;
		virtual ~Binding();

		Binding& operator=(const Binding& other) = delete;

		static std::shared_ptr<Binding> create(SigSlotBase* em, SigSlotBase* recv);

		void unbind();

	private:
		Binding(SigSlotBase* emitter, SigSlotBase* receiver);

		SigSlotBase* _emitter;
		SigSlotBase* _receiver;
	};


}
